package com.parking.order.controller;


import cn.hutool.core.bean.BeanUtil;
import com.parking.common.core.model.PageInfo;
import com.parking.common.core.model.Result;
import com.parking.common.core.util.JwtUtil;
import com.parking.order.model.dto.OrderDto;
import com.parking.order.model.dto.clientDto.UserOrderDto;
import com.parking.order.model.form.*;
import com.parking.order.model.form.clientForm.OrderTimeForm;
import com.parking.order.model.param.*;
import com.parking.order.service.IOrderInfoService;
import com.parking.order.util.BasicInfoUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author 吴彦祖
 * @since 2023年11月28日
 */
@RestController
@Api(tags = "订单信息")
@RequestMapping("/orderInfo")
public class OrderInfoController {
    /**
     * 订单信息业务层
     * */
    @Autowired
    private IOrderInfoService iOrderInfoService;

    /**
     * 添加订单
     * 参数: startTime 出租开始时间
     *       endTime  出租结束时间
     *       stallInfoId 车位Id
     *       userCarId   用户车辆Id
     *       authorization 用户Token
     *
     * 返回: certifiedInfoName    物业名称
     *      certifiedInfoTel     物业电话
     *      certifiedInfoAddress 物业地址
     *      time                 开始时间-结束时间
     *      enduHour             持续小时
     *      orderPrice           订单价格 = enduHour持续小时 * 普通/充电车位价格
     *      orderInfoState       订单状态 = 待支付
     *      orderAddTime         下单时间
     *      orderInfoNum         订单编号
     *      stallType            车位类型 0普通车位 1充电车位
     *      stallInfo            车位号 = stallInfoArea(车位区域) + stallInfoNum(车位编号)
     *      userCarPlate         车牌号
     */
    @PutMapping("/addOrder.user")
    @ApiOperation("添加订单")
    public Result<OrderDto> addOrder(@RequestBody @Valid AddOrderForm form, @RequestHeader String authorization) throws Exception {
        System.out.println("=================用户添加订单=====================");
        System.out.println("====================1.参数校验无误=====================");
        AddOrderParam param = BeanUtil.toBean(form, AddOrderParam.class);
        param.setUserId(JwtUtil.getUserId(authorization));
        OrderDto dto = iOrderInfoService.addOrder(param);
        return Result.getResult(OrderDto.class).setMessage("下单成功 请在2分钟内完成支付").setData(dto);
    }


    /**
     * 根据用户车辆Id查询关联订单
     * 参数: 用户车辆ID userCarId
     * 返回: List<UserOrderDto> 正在使用的用户订单Id 已取消和已完成的不要
     *      orderInfoId 订单Id
     *      orderInfoNum 订单编号
     * */
    @GetMapping("/selectUserOrderByUserCarId")
    @ApiOperation("根据用户车辆Id查询关联订单")
    Result<List<UserOrderDto>> selectUserOrderByUserCarId(@RequestParam("userCarId") Integer userCarId){
        List<UserOrderDto> dtos = iOrderInfoService.selectUserOrderByUserCarId(userCarId);
        return Result.getListResult(UserOrderDto.class).setData(dtos);
    }

    /**
     * 出租客查询订单信息
     * 参数  出租客token
     *      订单状态 orderInfoState 0预定订单 1正在进行 2超时订单 3取消订单 4完成订单
     *      订单更多状态
     *              0预定订单 -> 0未支付 1已支付
     *              1正在进行 -> 0未入场 1已入场
     *              2超时订单 -> 0未出场 1未支付
     *              3取消订单 -> 0未支付 1用户 2超时车位
     *              4完成订单 -> 0未评论 1好中评 2差评
     *      车位号 stallInfo
     *      分页页数 pageNum
     *      分页大小 pageSize
     * */
    @GetMapping("/findOrder.renters")
    @ApiOperation("出租客查询订单信息")
    Result<PageInfo> findOrderRenters(@Valid FindOrderRentersForm form, @RequestHeader String authorization) throws Exception {
        FindOrderRentersParam param = BeanUtil.toBean(form,FindOrderRentersParam.class);
        param.setRentersId(JwtUtil.getRentersId(authorization));
        PageInfo page = iOrderInfoService.findOrderRenters(param);
        return Result.getResult(PageInfo.class).setData(page).setMessage("出租客查询订单信息成功");
    }

    /**
     * 用户查询订单信息
     * 参数  用户token
     *      订单状态 orderInfoState 0预定订单 1正在进行 2超时订单 3取消订单 4完成订单
     *      订单更多状态
     *              0预定订单 -> 0未支付 1已支付
     *              1正在进行 -> 0未入场 1已入场
     *              2超时订单 -> 0未出场 1未支付
     *              3取消订单 -> 0未支付 1用户 2超时车位
     *              4完成订单 -> 0未评论 1已评论未回复 2已评论已回复
     *      车位号 stallInfo
     *      分页页数 pageNum
     *      分页大小 pageSize
     * */
    @GetMapping("/findOrder.user")
    @ApiOperation("用户查询订单信息")
    Result<PageInfo> findOrderUser(@Valid FindOrderUserForm form, @RequestHeader String authorization) throws Exception {
        FindOrderUserParam param = BeanUtil.toBean(form,FindOrderUserParam.class);
        param.setUserId(JwtUtil.getUserId(authorization));
        PageInfo page = iOrderInfoService.findOrderUser(param);
        return Result.getResult(PageInfo.class).setData(page).setMessage("用户查询订单信息成功");
    }

    /**
     * 物业查询订单信息
     * 参数  物业token
     *      订单状态 orderInfoState 0预定订单 1正在进行 2超时订单 3取消订单 4完成订单
     *      订单更多状态
     *              0预定订单 -> 0未支付 1已支付
     *              1正在进行 -> 0未入场 1已入场
     *              2超时订单 -> 0未出场 1未支付
     *              3取消订单 -> 0未支付 1用户 2超时车位
     *              4完成订单 -> 0未评论 1好中评 2差评未回复 3差评已回复
     *      车位号 stallInfo
     *      分页页数 pageNum
     *      分页大小 pageSize
     * */
    @GetMapping("/findOrder.certified")
    @ApiOperation("物业查询订单信息")
    Result<PageInfo> findOrderCertified(@Valid FindOrderCertifiedForm form, @RequestHeader String authorization) throws Exception {
        FindOrderCertifiedParam param = BeanUtil.toBean(form, FindOrderCertifiedParam.class);
        param.setCertifiedId(JwtUtil.getCertifiedAccountId(authorization));
        PageInfo page = iOrderInfoService.findOrderCertified(param);
        return Result.getResult(PageInfo.class).setData(page).setMessage("物业查询订单信息成功");
    }

    /**
     * 平台查询订单信息
     * 参数  平台token
     *      订单状态 orderInfoState 0预定订单 1正在进行 2超时订单 3取消订单 4完成订单
     *      订单更多状态
     *              0预定订单 -> 0未支付 1已支付
     *              1正在进行 -> 0未入场 1已入场
     *              2超时订单 -> 0未出场 1未支付
     *              3取消订单 -> 0未支付 1用户 2超时车位
     *              4完成订单 -> 0未评论 1好中评 2差评
     *      车位号 stallInfo
     *      物业信息Id certifiedInfoId
     *      分页页数 pageNum
     *      分页大小 pageSize
     * */
    @GetMapping("/findOrder.platform")
    @ApiOperation("平台查询订单信息")
    Result<PageInfo> findOrderUser(@Valid FindOrderPlatformForm form, @RequestHeader String authorization) throws Exception {
        FindOrderPlatformParam param = BeanUtil.toBean(form, FindOrderPlatformParam.class);
        param.setPlatformId(JwtUtil.getPlatformId(authorization));
        PageInfo page = iOrderInfoService.findOrderPlatform(param);
        return Result.getResult(PageInfo.class).setData(page).setMessage("平台查询订单信息成功");
    }

    /**
     * 支付宝回调接口
     * 参数 请求参数 HttpServletRequest
     * 返回 成功信息 "SUCCESS"
     * */
    @ApiOperation("支付宝回调接口")
    @PostMapping("/orderNotify")
    public String orderNotify(HttpServletRequest req) throws Exception {
        Map<String,String> params = new HashMap<String,String>();
        Map<String,String[]> requestParams = req.getParameterMap();
        for (String name : requestParams.keySet()) {
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            params.put(name, valueStr);
        }
        iOrderInfoService.updateOrderState(params);
        return "SUCCESS";
    }

    /**
     * 用户支付接口
     * 参数 orderInfoNum 订单编号 超时订单长度20 普通订单长度19
     *      authorization 用户token
     * */
    @ApiOperation("支付")
    @GetMapping("/pay.user")
    public void pay(@Valid PayForm form, HttpServletResponse resp, @RequestHeader String authorization) throws Exception {
        PayParam param = BeanUtil.toBean(form, PayParam.class);
        param.setUserId(JwtUtil.getUserId(authorization));
        String htmlForm = iOrderInfoService.pay(param);
        resp.setContentType("text/html;charset=utf-8");
        resp.getWriter().write(htmlForm);
    }

    /**
     * 用户退单
     * 参数 用户token authorization
     *     订单编号 orderInfoNum
     * 返回 额外信息 如是否半额退单等
     * */
    @ApiOperation("用户退单")
    @PutMapping("/refund.user")
    public Result<String> refund(@Valid RefundForm form, @RequestHeader String authorization) throws Exception {
        RefundParam param = BeanUtil.toBean(form, RefundParam.class);
        param.setUserId(JwtUtil.getUserId(authorization));
        String extraMessage = iOrderInfoService.refund(param);
        return Result.getResult(String.class).setMessage("用户退单成功"+extraMessage);
    }

    /**
     *userSelectTimeQuantum：筛选出符合时间范围内的所有订单的车位信息id
     * @param form 用户选择时间范围
     * @return  Set<Integer>   车位的ids集合
     *                          1.有时间交集的订单对应的车位Id
     *                          2.超时的订单对应的车位Id
     * @throws Exception
     */
    @ApiOperation("筛选出符合时间范围内的所有订单的车位信息id（车位模块调用）")
    @PostMapping("/userSelectTimeQuantum")
    public Result<Set<Integer>> userSelectTimeQuantum (@RequestBody OrderTimeForm form) throws Exception{
        Set<Integer> set = iOrderInfoService.userSelectTimeQuantum(form.getStartTime(),form.getEndTime());
        return Result.getSetResult(Integer.class).setData(set);
    }
}

